package org.bbmall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.bbmall.bean.member.*;
import org.bbmall.dao.*;
import org.bbmall.dto.member.*;
import org.bbmall.service.IMemberAnalysisService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 会员分析业务服务实现类
 */
@Service
@RequiredArgsConstructor
public class MemberAnalysisServiceImpl implements IMemberAnalysisService {

    private final AdsMemberCoreMetricsMapper coreMetricsMapper;
    private final AdsMemberLevelDisplayMapper levelDisplayMapper;
    private final AdsMemberTrendDisplayMapper trendDisplayMapper;
    private final AdsMemberTop5DisplayMapper top5DisplayMapper;
    private final AdsMemberPreferenceDisplayMapper preferenceDisplayMapper;

    /**
     * 获取会员分析仪表板所有数据
     */
    @Override
    public MemberDashboardDataDTO getMemberDashboardData(LocalDate today) {
        LocalDate lastMonth = today.minusMonths(1);

        MemberDashboardDataDTO dashboardData = new MemberDashboardDataDTO();

        // 1. 设置会员核心指标
        dashboardData.setMemberKpi(buildMemberKpiDTO(today, lastMonth));

        // 2. 设置会员等级分布
        dashboardData.setMemberLevels(buildMemberLevelsDTO(today));

        // 3. 设置会员月度消费趋势
        dashboardData.setMemberTrend(buildMemberTrendDTO());

        // 4. 设置高价值会员Top5
        dashboardData.setTopMembers(buildTopMembersDTO(today));

        // 5. 设置新会员转化率
        dashboardData.setConversionRate(buildConversionRateDTO(today));

        // 6. 设置会员偏好分析
        dashboardData.setMemberPreferences(buildMemberPreferencesDTO(today));

        return dashboardData;
    }

    /**
     * 构建会员核心指标DTO
     */
    private MemberKpiDTO buildMemberKpiDTO(LocalDate today, LocalDate lastMonth) {
        MemberKpiDTO kpiDTO = new MemberKpiDTO();

        // 获取今日会员核心指标
        AdsMemberCoreMetrics todayMetrics = getCoreMetricsByDate(today);
        if (todayMetrics != null) {
            kpiDTO.setTotalMembers(todayMetrics.getTotalMembers());
            kpiDTO.setActiveMembers(todayMetrics.getActiveMembers());
            kpiDTO.setActivityRate(todayMetrics.getActivityRate());
            kpiDTO.setAvgConsumption(todayMetrics.getAvgConsumption());
            kpiDTO.setRepurchaseRate(todayMetrics.getRepurchaseRate());
            kpiDTO.setRepurchaseRateChange(todayMetrics.getRepurchaseRateChange());
        } else {
            // 设置默认值
            kpiDTO.setTotalMembers(0);
            kpiDTO.setActiveMembers(0);
            kpiDTO.setActivityRate(BigDecimal.ZERO);
            kpiDTO.setAvgConsumption(BigDecimal.ZERO);
            kpiDTO.setRepurchaseRate(BigDecimal.ZERO);
            kpiDTO.setRepurchaseRateChange(BigDecimal.ZERO);
        }

        // 计算本月新增人数（从月度趋势表中获取）
        kpiDTO.setNewMembersThisMonth(getNewMembersThisMonth());

        // 计算会员平均消费高于非会员百分比（假设非会员平均消费为会员的70%）
        // 实际项目中应该从数据库获取非会员数据，这里使用模拟计算
        BigDecimal nonMemberAvgConsumption = todayMetrics != null ?
                todayMetrics.getAvgConsumption().multiply(BigDecimal.valueOf(0.7)) : BigDecimal.ZERO;
        BigDecimal higherPercentage = todayMetrics != null ?
                todayMetrics.getAvgConsumption()
                        .subtract(nonMemberAvgConsumption)
                        .divide(nonMemberAvgConsumption, 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100))
                        .setScale(1, RoundingMode.HALF_UP) : BigDecimal.ZERO;
        kpiDTO.setAvgConsumptionHigherThanNonMember(higherPercentage);

        return kpiDTO;
    }

    /**
     * 构建会员等级分布DTO
     */
    private List<MemberLevelDTO> buildMemberLevelsDTO(LocalDate statDate) {
        QueryWrapper<AdsMemberLevelDisplay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", statDate)
                .orderByDesc("member_count"); // 按会员数量降序排列

        List<AdsMemberLevelDisplay> levelDisplays = levelDisplayMapper.selectList(queryWrapper);

        return levelDisplays.stream()
                .map(level -> {
                    MemberLevelDTO dto = new MemberLevelDTO();
                    dto.setLevel(level.getMemberLevel());
                    dto.setMemberCount(level.getMemberCount());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建会员月度消费趋势DTO
     */
    private List<MemberTrendDTO> buildMemberTrendDTO() {
        // 获取最近12个月的数据
        QueryWrapper<AdsMemberTrendDisplay> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("stat_year")
                .orderByDesc("stat_month")
                .last("LIMIT 12");

        List<AdsMemberTrendDisplay> trendData = trendDisplayMapper.selectList(queryWrapper);

        // 按时间升序排列
        return trendData.stream()
                .sorted((a, b) -> {
                    int yearCompare = a.getStatYear().compareTo(b.getStatYear());
                    if (yearCompare != 0) return yearCompare;
                    return a.getStatMonth().compareTo(b.getStatMonth());
                })
                .map(trend -> {
                    MemberTrendDTO dto = new MemberTrendDTO();
                    dto.setMonth(trend.getStatYearMonth());
                    dto.setConsumptionAmount(trend.getConsumptionAmount());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建高价值会员Top5 DTO
     */
    private List<TopMemberDTO> buildTopMembersDTO(LocalDate statDate) {
        QueryWrapper<AdsMemberTop5Display> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", statDate)
                .orderByAsc("rank_num");

        List<AdsMemberTop5Display> topMembers = top5DisplayMapper.selectList(queryWrapper);

        return topMembers.stream()
                .map(member -> {
                    TopMemberDTO dto = new TopMemberDTO();
                    dto.setMemberId(member.getMemberId());
                    dto.setMemberName(member.getMemberName());
                    dto.setTotalConsumption(member.getTotalConsumption());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 构建新会员转化率DTO
     */
    private ConversionRateDTO buildConversionRateDTO(LocalDate statDate) {
        AdsMemberCoreMetrics coreMetrics = getCoreMetricsByDate(statDate);
        ConversionRateDTO dto = new ConversionRateDTO();

        if (coreMetrics != null) {
            // 使用新会员转化率作为首购率
            dto.setFirstPurchaseRate(coreMetrics.getNewMemberConversionRate());

            // 计算年度留存率（假设为复购率的85%）
            dto.setAnnualRetentionRate(coreMetrics.getRepurchaseRate()
                    .multiply(BigDecimal.valueOf(0.85))
                    .setScale(2, RoundingMode.HALF_UP));

            // 计算二次购买率（假设为复购率的75%）
            dto.setSecondPurchaseRate(coreMetrics.getRepurchaseRate()
                    .multiply(BigDecimal.valueOf(0.75))
                    .setScale(2, RoundingMode.HALF_UP));
        } else {
            dto.setFirstPurchaseRate(BigDecimal.ZERO);
            dto.setAnnualRetentionRate(BigDecimal.ZERO);
            dto.setSecondPurchaseRate(BigDecimal.ZERO);
        }

        return dto;
    }

    /**
     * 构建会员偏好分析DTO
     */
    private List<MemberPreferenceDTO> buildMemberPreferencesDTO(LocalDate statDate) {
        QueryWrapper<AdsMemberPreferenceDisplay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", statDate)
                .eq("preference_type", "CATEGORY") // 假设偏好类型为商品类别
                .orderByAsc("preference_rank");

        List<AdsMemberPreferenceDisplay> preferences = preferenceDisplayMapper.selectList(queryWrapper);

        return preferences.stream()
                .map(pref -> {
                    MemberPreferenceDTO dto = new MemberPreferenceDTO();
                    dto.setProductCategory(pref.getPreferenceValue());
                    dto.setPreferenceIndex(pref.getPreferenceRate());
                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 根据日期获取会员核心指标
     */
    private AdsMemberCoreMetrics getCoreMetricsByDate(LocalDate date) {
        QueryWrapper<AdsMemberCoreMetrics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_date", date);
        return coreMetricsMapper.selectOne(queryWrapper);
    }

    /**
     * 获取本月新增会员数
     */
    private Integer getNewMembersThisMonth() {
        YearMonth currentYearMonth = YearMonth.now();
        QueryWrapper<AdsMemberTrendDisplay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stat_year", currentYearMonth.getYear())
                .eq("stat_month", currentYearMonth.getMonthValue());

        AdsMemberTrendDisplay trend = trendDisplayMapper.selectOne(queryWrapper);
        return trend != null ? trend.getNewMembers() : 0;
    }
}